package cn.edu.zime.tjh.server;

import cn.edu.zime.tjh.handler.AsyncUDPServerHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

import java.util.function.Consumer;

public class AsyncEchoUDPServer {
    private static AsyncEchoUDPServer s_instance = null;

    public static final int PORT = 9000;
    
    private EventLoopGroup group;
    private Channel serverChannel;
    private Consumer<String> logCallback;

    private AsyncEchoUDPServer(){

    }

    public static AsyncEchoUDPServer getInstance(){
        if(s_instance == null){
            s_instance = new AsyncEchoUDPServer();
        }

        return s_instance;
    }
    
    public void setLogCallback(Consumer<String> logCallback) {
        this.logCallback = logCallback;
    }

    public void start(){
        start(PORT);
    }
    
    public void start(int port){
        group = new NioEventLoopGroup();
        try {
            // UDP使用Bootstrap而不是ServerBootstrap
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)  // 使用UDP通道
                    .option(ChannelOption.SO_BROADCAST, true)  // 允许广播
                    .handler(new ChannelInitializer<NioDatagramChannel>() {
                        @Override
                        protected void initChannel(NioDatagramChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new AsyncUDPServerHandler(logCallback));
                        }
                    });

            // 绑定端口（UDP没有连接概念，只有绑定）
            ChannelFuture f = b.bind(port).sync();
            serverChannel = f.channel();
            
            if (logCallback != null) {
                logCallback.accept("UDP Echo服务器已启动，监听端口: " + port);
            }
            
        } catch(Exception e){
            if (logCallback != null) {
                logCallback.accept("UDP服务器启动失败: " + e.getMessage());
            }
            e.printStackTrace();
        }
    }
    
    public void stop() {
        if (serverChannel != null) {
            serverChannel.close();
        }
        if (group != null) {
            group.shutdownGracefully();
        }
        if (logCallback != null) {
            logCallback.accept("UDP Echo服务器已停止");
        }
    }
    
    public boolean isRunning() {
        return serverChannel != null && serverChannel.isActive();
    }
}